<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>带电粒子和中性粒子</title>
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/css/bbfont.css">
    <link rel="stylesheet" href="/static/css/style.css">
    <link rel="stylesheet" href="qv.css">
    <style>
        .realtime > div {
            flex-grow: 1;
            position: relative;
        }

        .realtime {
            padding: 5px
        }

        .realtime > div > div {
            background: #FFF;
            position: absolute;
            /*height: 100%;*/
            left: 5px;
            right: 5px;
            top: 5px;
            bottom: 5px;
            overflow-y: auto;
        }

        .realtime header {
            padding: 5px 10px;
            background: darkcyan;
            color: #Fff
        }

        .realtime table th, .realtime table td {
            padding: 2px 5px !important;
        }

        /* Loading 遮罩层样式 */
        .loading-overlay {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(255, 255, 255, 0.95);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 1000;
        }

        .loading-container {
            text-align: center;
            padding: 30px;
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            min-width: 300px;
        }

        /* 进度条容器 */
        .progress-bar-container {
            width: 100%;
            height: 20px;
            background: #f0f0f0;
            border-radius: 10px;
            overflow: hidden;
            margin: 15px 0;
        }

        /* 进度条 */
        .progress-bar {
            height: 100%;
            background: linear-gradient(90deg, #4CAF50, #45a049);
            border-radius: 10px;
            transition: width 0.3s ease;
            position: relative;
            overflow: hidden;
        }

        /* 进度条动画效果 */
        .progress-bar::after {
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            bottom: 0;
            right: 0;
            background: linear-gradient(
                90deg,
                transparent,
                rgba(255, 255, 255, 0.3),
                transparent
            );
            animation: shimmer 2s infinite;
        }

        @keyframes shimmer {
            0% { transform: translateX(-100%); }
            100% { transform: translateX(100%); }
        }

        /* 进度文字 */
        .progress-text {
            font-size: 18px;
            color: #333;
            margin: 10px 0;
            font-weight: bold;
        }

        .progress-status {
            font-size: 14px;
            color: #666;
            margin: 5px 0;
        }

        /* 取消按钮 */
        .cancel-btn {
            margin-top: 20px;
            padding: 8px 24px;
            background: #f44336;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
        }

        .cancel-btn:hover {
            background: #da190b;
        }

        .cancel-btn:active {
            transform: scale(0.98);
        }

        /* 简单的加载提示样式 */
        .simple-loading {
            display: inline-block;
            margin-left: 10px;
            color: #666;
            font-size: 14px;
        }

        .loading-dots {
            display: inline-block;
        }

        .loading-dots::after {
            content: '.';
            animation: dots 1.5s steps(4, end) infinite;
        }

        @keyframes dots {
            0%, 20% { content: '.'; }
            40% { content: '..'; }
            60% { content: '...'; }
            80%, 100% { content: ''; }
        }
    </style>
</head>
<body id="viewer" class="M1">
<div id="CCC" style="padding: 4px 6px;">
    <button class="btn btn-primary btn-sm" id="realtime" onclick="main.realtime()">实时</button>
    <button class="btn btn-primary btn-sm ms-1" id="history" onclick="main.history()">历史</button>
    日期:
    <input id="day" type="date" value="">
    任务:
    <select id="task" class="sele-comp">
<!--        <option value="sci">科学数据头</option>-->
<!--        <option value="tia">热离子分析仪（TIA）</option>-->
<!--        <option value="tea">热电子分析仪（TEA）</option>-->
<!--        <option value="gia">气体与离子分析仪（GIA）</option>-->
    </select>
    <span class="history">
    时间: <input type="datetime-local">-<input type="datetime-local">
    仪器:
    <select id="modes" class="sele-comp" style="min-width: unset"></select>
    <label id="frm_max" hidden></label>
    <input id="frm_input" hidden><input id="frm_range" hidden>
    GIA 区域: <input id="gia_range" value="0,8192,64" title="开始,结束,合并间隔" placeholder="start,end,step" style="max-width: 120px;">
    <button class="btn btn-primary btn-sm" onclick="main.hist()"> 重绘</button>
<!--      <div class="flex-grow-1"></div>-->
    <button class="btn btn-primary btn-sm" onclick="main.exportCSV(this, main.$modes.val())"><i
            class="fa fa-file-text"></i>下载帧信息</button>
  </span>


</div>
<div class="w-100 position-relative" style="height: calc(100vh - 37px)">
    <div class="history h-100" style="position: relative;">
        <img class="h-100 m-auto" alt="" src="#">
    </div>
    <div class="realtime h-100 d-flex flex-row">
        <div class="sci">
            <div>
                <header>科学数据头</header>
                <table class="table small"></table>
            </div>
        </div>
        <div class="tia">
            <div>
                <header>热离子分析仪（TIA）</header>
                <table class="table small "></table>
            </div>
        </div>
        <div class="tea">
            <div>
                <header>热电子分析仪（TEA）</header>
                <table class="table small "></table>
            </div>
        </div>
        <div class="gia">
            <div>
                <header>气体与离子分析仪（GIA）</header>
                <table class="table small "></table>
            </div>
        </div>
        <div class="sia">
            <div>
                <header>太阳风离子分析仪（SIA）</header>
                <table class="table small "></table>
            </div>
        </div>
    </div>
    <!-- Loading 遮罩层（移动到外层容器，覆盖实时与历史两种视图） -->
    <div class="loading-overlay" id="loading" style="display: none;">
        <div class="loading-container">
            <div class="progress-status">正在绘制图表...</div>
            <div class="progress-bar-container">
                <div class="progress-bar" id="progressBar" style="width: 0%"></div>
            </div>
            <div class="progress-text" id="progressText">0%</div>
            <div class="progress-status" id="progressStatus">初始化...</div>
            <button class="cancel-btn" id="cancelBtn" onclick="main.cancelHistDrawing()">取消</button>
        </div>
    </div>
</div>
<script src="/static/js/jquery-3.6.0.min.js"></script>
<script src="/static/js/xtool.js?12"></script>
<script src="qv.js"></script>
<script>
    if (!Object.prototype.hasOwnProperty('items')) {
        Object.defineProperty(Object.prototype, 'items', {
            value: function (callback) { return Object.entries(this).map(callback) },
            enumerable: false
        });
    }

    const PARAMS = {
        sci: [
            {n: "同步码", k: "syn", v: new RawFmt(4).X, r: '4X'},
            {n: "仪器标识", k: "id", r: '2X'},
            {n: "源包帧序号", k: "sfc", r: '4X'},
            {n: "时间码", k: "time", v: BJT},
            {n: "仪器工作状态", k: "IS", r: '4X'},
            {n: "DPU正确指令计数", k: "DPU_CCC", r: '2X'},
            {n: "DPU指令代码", k: "DPU_code", r: '4X'},
            // r: {fmt: () => ""}
            //       {n: "平台状态信息", k: "PS", v: v=>v.join(','),r: {fmt: (v)=>v.map(i=>fmtHEX(i, 2))} },
            {n: "+A1.5V电压检测", k: "+A1.5V", v: XFMT_Fixed(), r: '2X'},
            {n: "+A3.3V电压检测", k: "+A3.3V", v: XFMT_Fixed(), r: '2X'},
            {n: "+A12V电压检测", k: "+A12V", v: XFMT_Fixed(), r: '2X'},
            {n: "-A12V电压检测", k: "-A12V", v: XFMT_Fixed(), r: '2X'},
            {n: "TIA温度检测", k: "TIA_Tpr", v: XFMT_Fixed(), r: '2X'},
            {n: "TEA温度检测", k: "TEA_Tpr", v: XFMT_Fixed(), r: '2X'},
            {n: "SIA温度检测", k: "SIA_Tpr", v: XFMT_Fixed(), r: '2X'},
            {n: "备份通道", k: "back_chn", r: '2X'},
            // <tr><th colspan="2"></th></tr>
            {n: "GIA+1.5V检测", k: "GIA+1.5V", v: XFMT_Fixed(), r: '2X'},
            {n: "GIA+3.3V检测", k: "GIA+3.3V", v: XFMT_Fixed(), r: '2X'},
            {n: "GIA MCP高压检测", k: "GIA_MCP_HV", v: XFMT_Fixed(), r: '2X'},
            // <tr><th colspan="2"></th></tr>
            {n: "TIA MCP高压检测", k: "TIA_MCP_HV", v: XFMT_Fixed(), r: '2X'},
            {n: "TIA+3.3V电源检测", k: "TIA+3.3v", v: XFMT_Fixed(), r: '2X'},
            {n: "TIA+1.5V电源检测", k: "TIA+1.5v", v: XFMT_Fixed(), r: '2X'},
            // <tr><th colspan="2"></th></tr>
            {n: "TEA MCP高压检测", k: "TEA_MCP_HV", v: XFMT_Fixed(), r: '2X'},
            {n: "TEA+3.3V电源检测", k: "TEA+3.3V", v: XFMT_Fixed(), r: '2X'},
            {n: "TEA+1.5V电源检测", k: "TEA+1.5V", v: XFMT_Fixed(), r: '2X'},
            // <tr><th colspan="2"></th></tr>
            {n: "SIA+1.5V电源检测", k: "SIA+1.5V", v: XFMT_Fixed(), r: '2X'},
            {n: "SIA+3.3V电源检测", k: "SIA+3.3V", v: XFMT_Fixed(), r: '2X'},
            {n: "SIA正主高压监测", k: "SIA+M_HV", v: XFMT_Fixed(), r: '2X'},
        ],
        gia: [
            {n: "时间码", k: "time", v: BJT},
            {n: "工作状态", k: "status", r: '4X'},
            {n: "正确指令计数", k: "CCC", r: '2X'},
            {n: "指令代码", k: "code", r: '2X'},
            {n: "参数表地址", k: "PT_addr", v: v => fmtHEX(v, 6), r: '6X'},
            {n: "灯丝电路状态设定", k: "FCS", r: '4X'},
            {n: "飞行时间测量范围设定", k: "FTMR", r: '4X'},
            {n: "门控高压使能时间设定", k: "ghv_enable_time", r: '4X'},
            {n: "门控高压禁止时间设定", k: "ghv_disable_time", r: '4X'},
            {n: "门控高压死区时间设定", k: "ghv_dead_time", r: '4X'},
            {n: "GIA SLOT个数设定", k: "sc", r: '4X'},
            {n: "周期参数设定", k: "cycle_param", r: '4X'},
            {n: "科学数据检测", k: "sdd", r: '6X'},
            // <tr><th colspan="2"></th></tr>
            // {n: "幅度超限次数设置", k: "amplitude_exceed", r: '2X'},
            // {n: "幅度上限阈值", k: "amplitude_upper", r: '4X'},
            // {n: "幅度下限阈值", k: "amplitude_lower", r: '4X'},
            {n: "阈值上限事件警界次数", k: "upper_cnt", r: '4X'},
            {n: "阈值下限事件警界次数", k: "lower_cnt", r: '4X'},
            {n: "前放阈值上限警界电压", k: "af_upper", v: v => v / 1000, r: '4X'},
            {n: "前放阈值下限警界电压", k: "af_lower", v: v => v / 1000, r: '4X'},
            {n: "电极3/4高压检测下限1", k: "3_4_lower_1", r: '2X'},
            {n: "电极3/4高压检测下限2", k: "3_4_lower2", r: '2X'},
            {n: "继电器工作状态", k: "worker_status", r: '2X'},
            {n: "模拟量工程参数序号", k: "param_index", r: '4X'},
            {n: "+1.5V电源检测", k: "+1.5V", v: XFMT_Fixed(), r: '4X'},
            {n: "+3.3V电源检测", k: "+3.3V", v: XFMT_Fixed(), r: '4X'},
            {n: "+12V电源检测", k: "+12V", v: XFMT_Fixed(), r: '4X'},
            {n: "-12V电源检测", k: "-12V", v: XFMT_Fixed(), r: '4X'},
            {n: "+24V电源检测", k: "+24V", v: XFMT_Fixed(), r: '4X'},
            {n: " 5V电源检测", k: "+5V", v: XFMT_Fixed(), r: '4X'},
            {n: "门控高压电流检测", k: "GHI", v: XFMT_Fixed(), r: '4X'},
            {n: "门控高压检测", k: "GHV", v: XFMT_Fixed(), r: '4X'},
            {n: "负主高压电流检测", k: "nMHI", v: XFMT_Fixed(), r: '4X'},
            {n: "负主高压检测", k: "nMHV", v: XFMT_Fixed(), r: '4X'},
            {n: "正主高压检测", k: "pMHV", v: XFMT_Fixed(), r: '4X'},
            {n: " MCP高压检测", k: "MPC_HV", v: XFMT_Fixed(), r: '4X'},
            {n: "灯丝电压检测", k: "F_V", v: XFMT_Fixed(), r: '4X'},
            {n: "栅网电压检测", k: "grid_V", v: XFMT_Fixed(), r: '4X'},
            {n: "比较器阈值检测", k: "comparator", v: XFMT_Fixed(), r: '4X'},
            {n: "漂移管和引出透镜的高压检测", k: "DTL_HV", v: XFMT_Fixed(), r: '4X'},
            {n: "发射极1234高压检测", k: "emit1234_HV", v: XFMT_Fixed(), r: '4X'},
            {n: "发射极56高压检测", k: "emit56_HV", v: XFMT_Fixed(), r: '4X'},
            {n: "前放阈值检测", k: "preamp", v: XFMT_Fixed(), r: '4X'},
            {n: "灯丝发射检测", k: "FE", v: XFMT_Fixed(), r: '4X'},
            {n: "灯丝阴极检测CH", k: "FC_CH", v: XFMT_Fixed(), r: '4X'},
            {n: "灯丝电源检测LV12", k: "FP_LV12", v: XFMT_Fixed(), r: '4X'},
            {n: "传感器温度检测", k: "ST", v: XFMT_Fixed(), r: '4X'},
            {n: "头部电极2345高压检测", k: "HE2345_HV", v: XFMT_Fixed(), r: '4X'},
        ],
        tia: [
            {n: "时间码", k: "time", v: BJT},
            {n: "工作状态标志", k: "status", r: '4X'},
            {n: "正确指令计数", k: "CCC", r: '2X'},
            {n: "指令代码", k: "code", r: '2X'},
            {n: "参数表地址", k: "PT_addr", v: v => fmtHEX(v, 6), r: '6X'},
            {n: "质量组查找表地址", k: "QT_addr", v: v => fmtHEX(v, 6), r: '6X'},
            {n: "方位角查找表地址", k: "AT_addr", v: v => fmtHEX(v, 6), r: '6X'},
            {n: "离子质量组个数", k: "MC", r: '2X'},
            {n: "离子方位角个数", k: "AC", r: '2X'},
            {n: "离子俯仰角个数", k: "PC", r: '2X'},
            {n: "离子能道个数", k: "EC", r: '2X'},
            {n: "飞行时间测量范围设定", k: "FTMR", r: '4X'},
            {n: "wait_slot", k: "wait_slot", r: '4X'},
            {n: "无损压缩参考字节", k: "ref_byte", r: '4X'},
            {n: "SLOT时间设定", k: "STS", r: '4X'},
            {n: "SLOT个数设定", k: "slot_C", r: '4X'},
            {n: "周期参数设定", k: "PPS", r: '4X'},
            {n: "科学数据检测", k: "SDT", r: '6X'},
            // <tr><th colspan="2"></th></tr>
            {n: "模拟量工程参数序号", k: "AEPI", r: '4X'},
            {n: "+1.5V电源检测", k: "+1.5V", v: XFMT_Fixed(), r: '4X'},
            {n: "+3.3V电源检测", k: "+3.3V", v: XFMT_Fixed(), r: '4X'},
            {n: "+5V电源检测", k: "+5V", v: XFMT_Fixed(), r: '4X'},
            {n: "+12V电源检测", k: "+12V", v: XFMT_Fixed(), r: '4X'},
            {n: "-12V电源检测", k: "-12V", v: XFMT_Fixed(), r: '4X'},
            {n: "+24V电源检测", k: "+24V", v: XFMT_Fixed(), r: '4X'},
            {n: "-24V电源检测", k: "-24V", v: XFMT_Fixed(), r: '4X'},
            {n: "负主高压检测", k: "nMHV", v: XFMT_Fixed(), r: '4X'},
            {n: "负主高压电流检测", k: "nMHI", v: XFMT_Fixed(), r: '4X'},
            {n: "微通道板高压检测", k: "MCP_HV", v: XFMT_Fixed(), r: '4X'},
            {n: "上扫描电压检测DF1", k: "UCV_df1", v: XFMT_Fixed(), r: '4X'},
            {n: "下扫描电压检测DF2", k: "LCV_df2", v: XFMT_Fixed(), r: '4X'},
            {n: "静电分析器电压检测ESA", k: "ESAV", v: XFMT_Fixed(), r: '4X'},
            {n: "门控高压低端检测", k: "GLV", v: XFMT_Fixed(), r: '4X'},
            {n: "门控高压电流检测", k: "GHI", v: XFMT_Fixed(), r: '4X'},
            {n: "门控高压检测", k: "GHV", v: XFMT_Fixed(), r: '4X'},
        ],
        tea: [
            {n: "时间码", k: "time", v: BJT},
            {n: "工作状态标志", k: "status", r: '4X'},
            {n: "正确指令计数", k: "CCC", r: '2X'},
            {n: "指令代码", k: "code", r: '2X'},
            {n: "参数表地址", k: "PT_addr", v: v => fmtHEX(v, 6), r: '6X'},
            {n: "wai_slot及无损压缩参考字节", k: "wai_slot", r: '4X'},
            {n: "wai_slot及无损压缩参考字节", k: "ref_byte", r: '2X'},
            {n: "电子方位角个数", k: "AC", r: '2X'},
            {n: "电子俯仰角个数", k: "PC", r: '2X'},
            {n: "电子能道个数", k: "EC", r: '2X'},
            {n: "飞行时间测量范围设定", k: "flight_time_measurement_range", r: '4X'},
            {n: "SLOT时间设定", k: "slot_time_setting", r: '4X'},
            {n: "SLOT个数设定", k: "slot_count", r: '4X'},
            {n: "周期参数设定", k: "cycle_param", r: '4X'},
            {n: "科学数据检测", k: "science_data_detection", r: '6X'},
            {n: "模拟量工程参数序号", k: "analog_engineering_param_index", r: '4X'},
            // {n: "", k: "_",v: v=>''},
            {n: "+1.5V电源检测", k: "+1.5V", v: XFMT_Fixed(), r: '4X'},
            {n: "+3.3V电源检测", k: "+3.3V", v: XFMT_Fixed(), r: '4X'},
            {n: "+5V电源检测", k: "+5V", v: XFMT_Fixed(), r: '4X'},
            {n: "+12V电源检测", k: "+12V", v: XFMT_Fixed(), r: '4X'},
            {n: "-12V电源检测", k: "-12V", v: XFMT_Fixed(), r: '4X'},
            {n: "+24V电源检测", k: "+24V", v: XFMT_Fixed(), r: '4X'},
            {n: "备用通道数据", k: "spare_channel_data", v: XFMT_Fixed(), r: '4X'},
            {n: "正主高压检测", k: "pMHV", v: XFMT_Fixed(), r: '4X'},
            {n: "正主高压电流检测", k: "pMNI", v: XFMT_Fixed(), r: '4X'},
            {n: "微通道板高压检测", k: "MCP_HV", v: XFMT_Fixed(), r: '4X'},
            {n: "上扫描电压检测DF1", k: "UCV_df1", v: XFMT_Fixed(), r: '4X'},
            {n: "下扫描电压检测DF2", k: "LCV_df2", v: XFMT_Fixed(), r: '4X'},
            {n: "静电分析器电压检测ESA", k: "ESAV", v: XFMT_Fixed(), r: '4X'},
        ],
        sia: [
            {n: "时间码", k: "time", v: BJT},
            {n: "工作状态", k: "status", r: '4X'},
            {n: "正确指令计数", k: "correct_cmd_count", r: '2X'},
            {n: "指令代码", k: "cmd_code", r: '2X'},
            {n: "参数表地址", k: "PT_addr", v: v => fmtHEX(v, 6), r: '6X'},
            {n: " SLOT时间", k: "slot_time", r: '4X'},
            {n: " SLOT个数", k: "slot_count", r: '4X'},
            {n: "高压脉冲参数设置", k: "high_voltage_pulse_param", r: '4X'},
            {n: "模拟量工程参数序号", k: "analog_engineering_param_index", r: '4X'},
            // <tr><th colspan="2"></th></tr>
            {n: "科学数据通道1电压检测", k: "SDC_1V", v: XFMT_Fixed(), r: '4X'},
            {n: "科学数据通道2电压检测", k: "SDC_2V", v: XFMT_Fixed(), r: '4X'},
            {n: "科学数据通道3电压检测", k: "SDC_3V", v: XFMT_Fixed(), r: '4X'},
            {n: "科学数据通道4电压检测", k: "SDC_4V", v: XFMT_Fixed(), r: '4X'},
            {n: "科学数据通道5电压检测", k: "SDC_5V", v: XFMT_Fixed(), r: '4X'},
            {n: "主高压PHV检测", k: "MH_PHV", v: XFMT_Fixed(), r: '4X'},
            {n: "扫描高压检测", k: "SHV", v: XFMT_Fixed(), r: '4X'},
            {n: "+12V电压检测", k: "+12V", v: XFMT_Fixed(), r: '4X'},
            {n: "-12V电压检测", k: "-12V", v: XFMT_Fixed(), r: '4X'},
            {n: "+3.3V电源检测", k: "+3.3V", v: XFMT_Fixed(), r: '4X'},
            {n: "+2.5V电源检测", k: "+2.5V", v: XFMT_Fixed(), r: '4X'},
            {n: "+24V电压检测", k: "+24V", v: XFMT_Fixed(), r: '4X'},
            {n: "高压电流检测", k: "HVC", v: XFMT_Fixed(), r: '4X'},
            {n: "+5V电源检测", k: "+5V", v: XFMT_Fixed(), r: '4X'},
            {n: "抑制高压检测", k: "sup_HV", v: XFMT_Fixed(), r: '4X'}
        ],
    }

    class XView extends Realtime {
        constructor() {
            super('CANPA', $STATION)
            this._params = Object.keys(PARAMS).reduce((acc, k) => {
                acc[k] = PARAMS[k].map($param)
                return acc
            }, {})
            this.$sci = $$('.sci table')
            this.$gia = $$('.gia table')
            this.$tia = $$('.tia table')
            this.$tea = $$('.tea table')
            this.$sia = $$('.sia table')
            this.$hst = $('.history');
            this.$rlt = $('.realtime');
            this.$modes = $('#modes');
            this.modes = {}
            this.$modes.change(this.hist.bind(this))
            this.$dates = $$$('[type="datetime-local"]')

            // 新增属性
            this.drawingTimer = null;      // 进度条定时器
            this.currentProgress = 0;       // 当前进度
            this.isDrawingCancelled = false; // 是否取消绘制
            this.currentImgElement = null;   // 当前加载的图片元素
        }

      async onTask() {
        // 显示加载提示
        $('#loading').show();
        $('.loading-container .progress-status').first().text('正在切换任务...');
        $('#progressStatus').text('正在加载新任务的历史数据...');
        $('#progressBar').parent().hide();
        $('#progressText').hide();
        $('#cancelBtn').hide();

        try {
            this.cur_task = this.$task.value;
            await this.history()
        } finally {
            $('#loading').hide();
            // 恢复进度条相关元素
            $('#progressBar').parent().show();
            $('#progressText').show();
            $('#cancelBtn').show();
        }
      }

      renderMode() {
            // return super.renderMode();
        }

        get mode() {
            return 'tia';
        }

        async load_frames(task) {
            await super.load_frames(task);
            if (this.frames_ori.length) {
                this.modes = {}
                this.frames_ori.map(fr => {
                    let i = fr.info;
                    ['gia', 'tia', 'tea', 'sia'].forEach(v => {
                        let p = v;// + '-' + i[v]['PT_addr'].toString(16).padStart(6, '0')
                        this.modes[p] = (this.modes[p] || 0) + (i[p] ? 1 : 0)
                    })
                    this.$modes.html(this.modes.items(([k, n]) => `<option value="${k}">${k.toUpperCase()}: ${n}</option>`))
                })
                this.$dates[0].value = BJT(this.frames_ori[0].st)
                this.$dates[1].value = BJT(this.frames_ori[this.frames_ori.length - 1].st)
            }
        }

        seek(i) {

        }

        async hist() {
            // 重置状态
            this.isDrawingCancelled = false;
            this.currentProgress = 0;

            try {
                // 获取参数并检查选项计数
                let mo = this.$modes.val()
                let selectedText = (this.$modes && this.$modes[0] && this.$modes[0].options && this.$modes[0].selectedIndex >= 0)
                  ? this.$modes[0].options[this.$modes[0].selectedIndex].text
                  : '';
                let m = selectedText.match(/:\s*(\d+)/);
                let cnt = m ? parseInt(m[1], 10) : NaN;
                if (!isNaN(cnt) && cnt === 0) {
                    alert('该模式计数为 0，无需绘制图像');
                    return;
                }

                // 显示加载界面
                $('#loading').show();
                $('#progressBar').css('width', '0%');
                $('#progressText').text('0%');
                $('#progressStatus').text('正在准备数据...');

                this.filter_frames(mo)
                if (mo.includes('gia')) mo = mo + '&slice=' + $$('#gia_range').value
                let x = new Date().getMilliseconds();
                let s = new Date(this.$dates[0].value + '+0800').getTime()
                let e = new Date(this.$dates[1].value + '+0800').getTime()

                // 启动模拟进度
                this.startProgressSimulation();

                // 设置图片源
                let img = $$('.history img');
                this.currentImgElement = img;

                // 创建新的图片元素来加载（避免直接修改显示的图片）
                let tempImg = new Image();

                tempImg.onload = () => {
                    if (!this.isDrawingCancelled) {
                        // 快速完成进度条
                        this.completeProgress();
                        // 显示图片
                        img.src = tempImg.src;
                        setTimeout(() => {
                            $('#loading').hide();
                            this.clearDrawingState();
                        }, 500);
                    }
                };

                tempImg.onerror = () => {
                    if (!this.isDrawingCancelled) {
                        this.clearDrawingState();
                        $('#loading').hide();
                        alert('图表加载失败，请重试');
                    }
                };

                // 开始加载图片
                tempImg.src = `/-/omsp.canpa?t=${this.cur_task}&mode=${mo}&s=${s}&e=${e}&x=${x}`;

            } catch (error) {
                this.clearDrawingState();
                $('#loading').hide();
                console.error('绘制图表出错:', error);
                alert('绘制图表时出现错误');
            }
        }

        // 启动进度模拟
        startProgressSimulation() {
            // 基于60秒的预期时间模拟进度
            const expectedDuration = 60000; // 60秒
            const updateInterval = 200; // 每200ms更新一次
            const maxSimulatedProgress = 95; // 最高模拟到95%

            let startTime = Date.now();

            // 清除旧的定时器
            if (this.drawingTimer) {
                clearInterval(this.drawingTimer);
            }

            this.drawingTimer = setInterval(() => {
                if (this.isDrawingCancelled) {
                    clearInterval(this.drawingTimer);
                    return;
                }

                let elapsed = Date.now() - startTime;
                let progress = Math.min((elapsed / expectedDuration) * maxSimulatedProgress, maxSimulatedProgress);

                // 使用缓动函数让进度更自然
                progress = this.easeOutCubic(progress / maxSimulatedProgress) * maxSimulatedProgress;

                this.currentProgress = Math.floor(progress);
                this.updateProgressUI(this.currentProgress);

                // 更新状态文字
                if (this.currentProgress < 30) {
                    $('#progressStatus').text('正在连接服务器...');
                } else if (this.currentProgress < 60) {
                    $('#progressStatus').text('正在处理数据...');
                } else if (this.currentProgress < 90) {
                    $('#progressStatus').text('正在生成图表...');
                } else {
                    $('#progressStatus').text('即将完成...');
                }

                // 到达95%后停止模拟
                if (this.currentProgress >= maxSimulatedProgress) {
                    clearInterval(this.drawingTimer);
                }
            }, updateInterval);
        }

        // 缓动函数
        easeOutCubic(t) {
            return 1 - Math.pow(1 - t, 3);
        }

        // 更新进度UI
        updateProgressUI(progress) {
            $('#progressBar').css('width', progress + '%');
            $('#progressText').text(progress + '%');
        }

        // 完成进度（快速从当前进度到100%）
        completeProgress() {
            clearInterval(this.drawingTimer);

            let currentProg = this.currentProgress;
            let steps = 10;
            let stepSize = (100 - currentProg) / steps;
            let stepCount = 0;

            let completeTimer = setInterval(() => {
                stepCount++;
                currentProg += stepSize;

                if (stepCount >= steps) {
                    currentProg = 100;
                    clearInterval(completeTimer);
                    $('#progressStatus').text('完成！');
                }

                this.updateProgressUI(Math.floor(currentProg));
            }, 30);
        }

        // 取消绘制
        cancelHistDrawing() {
            this.isDrawingCancelled = true;

            // 中止图片加载
            if (this.currentImgElement) {
                this.currentImgElement.src = '#';
            }

            // 清理状态
            this.clearDrawingState();

            // 隐藏加载界面
            $('#loading').hide();

            // 提示用户
            console.log('图表绘制已取消');
        }

        // 清理绘制状态
        clearDrawingState() {
            if (this.drawingTimer) {
                clearInterval(this.drawingTimer);
                this.drawingTimer = null;
            }
            this.currentProgress = 0;
            this.isDrawingCancelled = false;
            this.currentImgElement = null;
        }

        async history() {
            // 显示加载提示
            let $historyBtn = $('#history');
            let originalText = $historyBtn.text();
            $historyBtn.html('历史 <span class="loading-dots"></span>');
            $historyBtn.prop('disabled', true);

            // 显示加载遮罩（复用现有的loading界面，但调整文字）
            $('#loading').show();
            $('#progressBar').parent().hide(); // 隐藏进度条容器
            $('#progressText').hide(); // 隐藏百分比
            $('#cancelBtn').hide(); // 隐藏取消按钮
            $('.loading-container .progress-status').first().text('正在加载历史数据...');
            $('#progressStatus').text('请稍候，这可能需要一些时间...');

            // 让浏览器先渲染出以上UI后再进入耗时流程
            await new Promise(requestAnimationFrame);
            await new Promise(resolve => setTimeout(resolve, 0));

            try {
                // 执行父类的history方法（主要耗时操作）
                await super.history();

                // 如果有load_frames的调用（目前被注释）
                // await this.load_frames(this.cur_task)

                // 切换显示
                this.$rlt.hide()
                this.$hst.show()

            } catch (error) {
                console.error('加载历史数据失败:', error);
                alert('加载历史数据时出错，请重试');
            } finally {
                // 恢复按钮状态
                $historyBtn.text(originalText);
                $historyBtn.prop('disabled', false);

                // 隐藏加载界面
                $('#loading').hide();

                // 恢复进度条相关元素的显示状态（为后续图表绘制做准备）
                $('#progressBar').parent().show();
                $('#progressText').show();
                $('#cancelBtn').show();
            }
        }

        filter_frames(mode) {
            this.frames = mode ? this.frames_ori.filter(
                v => (mode === undefined || v.info[mode.toLowerCase()])
            ).map(
                (v, i) => Object.assign(v, {frm_: i})
            ) : this.frames_ori.map((v, i) => Object.assign(v, {frm_: i}))
        }

        realtime() {
            super.realtime();
            this.$hst.hide()
            this.$rlt.show()
        }

        async newframe(d) {
            await super.newframe(d);
            this.show_frame(d)
        }

        exportCSV(btn, key) {
            btn.disabled = true
            let com_key = 'sci'
            let a = null;
            try {
                let params = key ? this._params[key] : [];
                let com_params = this._params[com_key];
                let title = com_params.map(v => v.csv_h).join(',') + "," + params.map(v => v.csv_h).join(',')
                let data = [new Uint8Array([0xEF, 0xBB, 0xBF]), `时间,${title}\n`];
                this.frames.forEach(v => {
                    let info = v.info
                    let com_line = com_params.map(c => c.csv_b(info)).join(',')
                    let p =  info[key];
                    let line = params.map(c => c.csv_b(p)).join(",")
                    // data.push(`${BJT(v.st)},${line}\n`)
                    data.push(`"${BJT(v.st)}",${com_line},${line}\n`)
                })
                let blob = new Blob(data, {'content_type': 'application/csv;charset=utf8'});
                let a = document.createElement('a');
                a.href = URL.createObjectURL(blob);
                let t = this.task;
                a.download = `${this.station}_${this.key}_${this.task.label.split('/')[0]}_${key || 'X'}.csv`
                a.click()
            } finally {
                if (a) {
                    setTimeout(() => {
                        URL.revokeObjectURL(a.href)
                    }, 1000)
                }
                btn.disabled = false
            }
        }

        show_frame(msg) {
            let d = msg.info
            let v = d;
            this.$sci.innerHTML = this._params['sci'].map(c => c.view_tr(v)).join('')
            Object.keys(PARAMS).filter(k => k != 'sci').forEach(k => {
                v = d[k] || 0
                if (v) {
                    this['$' + k].innerHTML = this._params[k].map(c => c.view_tr(v)).join('')
                } else {
                    this['$' + k].innerHTML = ''
                }
            })
        }

        // 初始化页面
        async initPage() {
            try {
                // 异步调用realtime，完成后隐藏loading
                await this.realtime();
                // 避免过早隐藏初始加载遮罩，给浏览器一个渲染节拍
                await new Promise(resolve => setTimeout(resolve, 300));
                hidePageLoading();
                this.$rlt.show();
            } catch (error) {
                console.error('页面初始化失败:', error);
                hidePageLoading();
                // 即使失败也显示页面，让用户可以切换到历史模式
                this.$rlt.show();
            }
        }
    }

    var main = new XView()

    // 显示页面加载中
    function showPageLoading() {
        // 显示loading，隐藏所有内容
        $('#loading').show();
        $('.loading-container .progress-status').first().text('正在初始化页面...');
        $('#progressStatus').text('正在建立连接，请稍候...');

        // 显示模拟进度条
        $('#progressBar').parent().show();
        $('#progressText').show();
        $('#cancelBtn').hide(); // 初始化时不能取消

        // 启动进度模拟（30秒）
        let progress = 0;
        let timer = setInterval(() => {
            progress = Math.min(progress + 3, 95);
            $('#progressBar').css('width', progress + '%');
            $('#progressText').text(progress + '%');

            if (progress >= 95) {
                clearInterval(timer);
            }
        }, 900); // 每900ms增加3%，约30秒到95%

        // 保存定时器供后续清理
        window.pageLoadingTimer = timer;
    }

    // 隐藏页面加载提示
    function hidePageLoading() {
        if (window.pageLoadingTimer) {
            clearInterval(window.pageLoadingTimer);
        }

        // 快速完成到100%
        $('#progressBar').css('width', '100%');
        $('#progressText').text('100%');
        $('#progressStatus').text('加载完成！');

        setTimeout(() => {
            $('#loading').hide();
        }, 500);
    }

    // 页面加载时显示loading
    showPageLoading();
    // 异步启动实时模式
    main.initPage();
</script>
</body>
</html>
